﻿#include "ddutestthread.h"

#include <QException>
#include <QWaitCondition>
#include<QTcpSocket>
#include <QDir>
#include"Tool/MsgGenerate.h"
DDUTestThread::DDUTestThread(QObject *parent):QThread(parent)
{

}

DDUTestThread::~DDUTestThread()
{
    _DDUProtocalData->clear();
    _index=0;
}


void DDUTestThread::SetConfigData(ConfigData *configdata)
{
    _configData = configdata;
}


void DDUTestThread::SetTestData( QMap<QString,QList<QString>>&testData, int nId)
{
    _DDUProtocalData = &testData;

    _index = nId;
}

void DDUTestThread::Stop()
{

    condition.wakeAll();
    bStop =true;



}

void DDUTestThread::SetIndex(int index)
{
    _index = index;
}

int DDUTestThread::GetIndex()
{
    return _index;
}

void DDUTestThread::acceptImg(const cv::Mat &img)
{

    _receiveImg = img;
    condition.wakeAll();

}

void DDUTestThread::SetWorkFinishCode(int ncode)
{
    _WorkFinishCode = ncode;
}

QString DDUTestThread::GenerateSendMsg(int id)
{
    //发送数据组成为 comid,byte,bit,size
    QVector<QString> vSenddata;
    vSenddata.resize(4);
    QString strSend;

    for (auto iter = _DDUProtocalData->begin(); iter != _DDUProtocalData->end(); ++iter)
    {
        if(iter.key().contains("Comid"))
        {
            vSenddata[0]=iter.value()[id];
            _recentComid=iter.value()[id].toInt();
        }
        if(iter.key().contains("Byte"))
        {
            vSenddata[1]=iter.value()[id];
        }
        if(iter.key().contains("Bit"))
        {
            vSenddata[2]=iter.value()[id];
        }
        if(iter.key().contains("Size"))
        {
            vSenddata[3]=iter.value()[id];
        }

    }

    for (int var = 0; var < vSenddata.size(); ++var) {
        strSend+=vSenddata[var];
        strSend+=",";
    }
    //去除最后多余逗号
    strSend.chop(1);
    return strSend;
}

QVector<QString> DDUTestThread::GenerateCheckData(int id)
{

    QVector<QString> vCheckData;
    vCheckData.resize(3);
    for (auto iter = _DDUProtocalData->begin(); iter != _DDUProtocalData->end(); ++iter)
    {
        if(iter.key().contains("Description"))
        {
            vCheckData[0]=iter.value()[id];
        }
        if(iter.key().contains("Event Code"))
        {
            vCheckData[1]=iter.value()[id];
        }
        if(iter.key().contains("Train Event Level"))
        {
            vCheckData[2]=iter.value()[id];
        }
        //        if(iter.key().contains("车号"))
        //        {
        //            vCheckData[3]=iter.value()[id];
        //        }

    }
    return vCheckData;
}

int DDUTestThread::GetMaxRowOfData()
{
    if(_DDUProtocalData->isEmpty())
        return 0;
    int maxRow = 0;
    for (auto iter = _DDUProtocalData->begin(); iter !=_DDUProtocalData->end(); ++iter)
    {
        int RecentCount =iter.value().count();
        maxRow=maxRow>RecentCount?maxRow:RecentCount;
    }
    return maxRow;
}

//添加接收数据的检测
bool DDUTestThread::IsOCRDataRight(QVector<QString> Checkdata,QStringList strReceiveList)
{
    QString str;
    for (int var = 0; var < strReceiveList.count(); ++var) {
        str += strReceiveList[var];
        str += ",";
        QString temp =strReceiveList[var];
        temp = temp.toUpper();  //转换为大写
        if(temp.size()>=3&&temp.size()<=6)
            temp= ReplaceOOfZero(temp); //替换O为0
        strReceiveList[var]=temp;
    }

    QString strCheck;
    for (int i = 0; i < Checkdata.size(); ++i) {
        strCheck+=Checkdata[i];
    }

    QVector<bool> vectorCheck;
    vectorCheck.resize(Checkdata.size());
    for (int i = 0; i < Checkdata.size(); ++i)
    {

        if(strReceiveList.contains(Checkdata[i]))
            vectorCheck[i]=true;
        else
        {
            vectorCheck[i]=false;
            emit SendProcedureMsg("error Content:"+Checkdata[i]);
        }
    }


    for (int i = 0; i < vectorCheck.size(); ++i)
    {
        if(!vectorCheck[i])
            return false;
    }
    return true;
}


QString DDUTestThread::ReplaceOOfZero(const QString &str)
{
    QString temp = str;
    temp.replace("O","0");
    temp.replace("o","0");
    return temp;
}

QString DDUTestThread::generateCleanMsg(int comid)
{
    QString senddata = QString::number(comid)+",0,0,1";
    senddata= messageGenarate::GenerateConfigMsg(MSG_CONTENT::PUTVALUE,senddata);
    return senddata;
}

void DDUTestThread::SendcleanMsg(int comid)
{
    QString strSend = generateCleanMsg(comid);
}

void DDUTestThread::TestSpecialID(int id)
{

}


void DDUTestThread::run()
{

    _tcpClient.connectToServer(_configData->strIP,_configData->strPort.toInt());
    bStop=false;

    int nMaxRow = GetMaxRowOfData();
    qDebug()<<nMaxRow<<endl;
    int nSnapWait =_configData->snapWaitTime.toInt();
    for(int i=_index;i<nMaxRow;i++)
    {
        _index=i;
        // 1.发送测试数据到DDU
        QString sendData = GenerateSendMsg(i);
        emit SendProcedureMsg("SendData:["+QString::number(_index+1)+"]"+sendData);
        QVector<QString> checkdata= GenerateCheckData(i);
        emit SendProcedureMsg("Generate checkdata:"+checkdata.toList().join(","));

        if(_lastComid!=0&&_lastComid!=_recentComid)
        {
            //发送清空DDU错误消息指令
            QString clearMsg = generateCleanMsg(_lastComid);
            _tcpClient.sendData(sendData);
            _lastComid=_recentComid;
        }
        //生成发送数据
        sendData= messageGenarate::GenerateConfigMsg(MSG_CONTENT::PUTVALUE,sendData);
        _tcpClient.sendData(sendData);
        //    2.延时，用于DDU通信，然后错误信息显示
        QThread::msleep(nSnapWait);
        //    3.发送截屏信号
        emit SendOCRMdg();
        //    4.图像识别，返回结果
        _mutex.lock();
        qDebug()<<"lock"<<endl;
        condition.wait(&_mutex,1000*20);       //等待20s

        qDebug()<<"continue"<<endl;
        try
        {
            //5.识别
            QStringList list;
            auto ocr_result =ppocr.ocr( _receiveImg,true,true,false);
            //    6.发送数据与结果比对

            for (int var = 0; var < ocr_result.size(); ++var)
            {
                list<<ocr_result[var].text.c_str();

            }
            emit SendProcedureMsg("OCR Result:"+list.join(","));

            //数组存在问题 待修改
            if(IsOCRDataRight(checkdata,list))
            {
                if(_configData->bSaveTargetRegion)
                {
                    QString strimgPath =GenerateSavePath(i);
                    cvMat2Qimage(_receiveImg).save(strimgPath);
                    qDebug()<<"img filename:"<<strimgPath<<endl;
                    //                cv::imwrite 存在路径的中文字符串Utf8格式需求
                    //                cv::imwrite(strimgPath.toStdString(),_receiveImg);
                    //                cv::imwrite("C:/image/PM222G61312-滁宁DDU系统/uuu.png",_receiveImg);
                }

                emit  TestResult(i,true,QString::fromLocal8Bit("通过"));
            }
            else
            {
                if(_configData->bSaveTargetRegion)
                {
                    QString strimgPath =GenerateSavePath(i,false);
                    cvMat2Qimage(_receiveImg).save(strimgPath);
                }
                emit  TestResult(i,false,QString::fromLocal8Bit("失败"));
            }

        } catch (std::exception& ex)
        {
            QString exMsg(ex.what());
            emit SendProcedureMsg(exMsg);
        }

        _mutex.unlock();
        qDebug()<<"unlock"<<endl;

        if(bStop)
        {
//            emit WorkFinish(_WorkFinishCode);
            break;
        }
    }

    //恢复按钮显示
    emit WorkFinish(2);
    //断开连接
    _tcpClient.Disconnect();
}

QString DDUTestThread::GenerateSavePath(int nid,bool bOK)
{
    //检测创建文件夹
    QString str;
    if(bOK)
        //        str=_configData->imgSavePath+"/";
        str=_configData->imgSavePath+"/"+ _configData->strProtocalName+"/"+"correct"+"/";
    else
        str=_configData->imgSavePath+"/"+ _configData->strProtocalName+"/"+"Error"+"/";
    QDir dir(str);
    if(!dir.exists())
        dir.mkpath(str);

    QString strID = QString::number(nid+1);
    QString strFormat = ".png";
    str+=strID+strFormat;

    return str;
}

QImage DDUTestThread::cvMat2Qimage(const cv::Mat &mat)
{
    QImage image;
    switch(mat.type())
    {
    case CV_8UC1:
        // QImage构造：数据，宽度，高度，每行多少字节，存储结构
        image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Grayscale8);
        break;
    case CV_8UC3:
        image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
        image = image.rgbSwapped(); // BRG转为RGB
        // Qt5.14增加了Format_BGR888
        // image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.cols * 3, QImage::Format_BGR888);
        break;
    case CV_8UC4:
        image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
        break;
    case CV_16UC4:
        image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGBA64);
        image = image.rgbSwapped(); // BRG转为RGB
        break;
    }
    return image;

}
